package core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import common.Notify ;
import common.Service;
import common.Servlet;
import common.Validate;
import dict.CommonDict;
import dict.TransactionDict;
import dicts.GlobalDict;
import entities.TSubject;
import entities.TTransaction;
import entities.TWebsite;
import interfaces.ISubjectService;
import interfaces.ITransactionService;
import interfaces.IWebsiteService;
import net.sf.json.JSONObject;
import util.LogUtil;
import utils.DateUtil;
import utils.DigestUtil;
import utils.NumberUtil ;
import utils.StringUtil;

public class Check extends Servlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public synchronized void process(HttpServletRequest request, HttpServletResponse response) throws Exception {

		System.out.println(DateUtil.format(new Date(), DateUtil.DATETIME) + " | 交易查询");

		// 初始化service
		ISubjectService subjectService = (ISubjectService) Service.create(ISubjectService.class);
		IWebsiteService websiteService = (IWebsiteService) Service.create(IWebsiteService.class);
		ITransactionService transactionService = (ITransactionService) Service.create(ITransactionService.class);

		Map<String, Object> paramMap = Collections.synchronizedMap(new HashMap<String, Object>());
		JSONObject jsonResult = new JSONObject();

		// 初始化bean和属性
		TSubject subject = new TSubject();
		TWebsite website = new TWebsite();
		TTransaction transaction = new TTransaction();

		// 验证系统
		if (GlobalDict.LINUX.equalsIgnoreCase(System.getProperty("os.name")) && !CommonDict.HOST.equals(request.getServerName())) {
			response.getWriter().print(Validate.result(TransactionDict.ILLAGEL_ACCESS, TransactionDict.MESSAGES.get(TransactionDict.ILLAGEL_ACCESS)));
			return;
		}

		// 校验参数 ( 名称,值,校验模式,边界 )
		List<Object[]> parameterList = Collections.synchronizedList(new ArrayList<Object[]>());
		parameterList.add(new Object[] { "version", request.getParameter("version"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "no", request.getParameter("no"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 5, 6 });
		parameterList.add(new Object[] { "order", request.getParameter("order"), Validate.NOTEMPTY | Validate.CHARNUMBER | Validate.EXCEEDLENGTH, 0, 50 });
		parameterList.add(new Object[] { "site", request.getParameter("site"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH | Validate.NOHTTPHEADER, 0, 100 });
		parameterList.add(new Object[] { "signature", request.getParameter("signature"), Validate.NOTEMPTY | Validate.EXCEEDLENGTH, 0, 500 });

		JSONObject validateResult = Validate.validate(parameterList);
		LogUtil.check(Validate.summary(parameterList));

		if (!StringUtil.isEmpty(validateResult)) {
			System.out.println ( validateResult.toString() ) ;
			response.getWriter().print(validateResult.toString());
			return;
		}

		if (!request.getParameter("version").equals(GlobalDict.VERSION)) {
			response.getWriter().print(Validate.result(TransactionDict.VERSION_ERROR, TransactionDict.MESSAGES.get(TransactionDict.VERSION_ERROR)));
			return;
		}

		// 校验子账户存在和状态
		try {
			subject = subjectService.fetch(request.getParameter("no"));
		} catch (Exception e) {
			response.getWriter().print(Validate.result(TransactionDict.SUBJECT_FETCH_EXCEPTION, TransactionDict.MESSAGES.get(TransactionDict.SUBJECT_FETCH_EXCEPTION)));
			return;
		}

		if (subject == null) {
			response.getWriter().print(Validate.result(TransactionDict.SUBJECT_NOT_EXIST, TransactionDict.MESSAGES.get(TransactionDict.SUBJECT_NOT_EXIST)));
			return;
		}

		if (!subject.getSubState().equals("1")) {
			response.getWriter().print(Validate.result(TransactionDict.SUBJECT_STATUS_EXCEPTION, TransactionDict.MESSAGES.get(TransactionDict.SUBJECT_STATUS_EXCEPTION)));
			return;
		}

		// 校验数字签名
		if (!DigestUtil.sha256(subject.getSubNo() + request.getParameter("order")+ subject.getSubKey()).equalsIgnoreCase(request.getParameter("signature"))) {
			response.getWriter().print(Validate.result(TransactionDict.SIGNATURE_INCORRECT, TransactionDict.MESSAGES.get(TransactionDict.SIGNATURE_INCORRECT)));
			return;
		}

		// 交易网站存在和状态
		try {
			paramMap = Collections.synchronizedMap(new HashMap<String, Object>());
			paramMap.put("webNo", StringUtil.split(subject.getSubNo()));
			paramMap.put("webAddress", request.getParameter("site"));
			website = websiteService.single(paramMap);
		} catch (Exception e) {
			response.getWriter().print(Validate.result(TransactionDict.WEBSITE_FETCH_EXCEPTION, TransactionDict.MESSAGES.get(TransactionDict.WEBSITE_FETCH_EXCEPTION)));
			return;
		}

		// 网站不存在报错
		if (website == null) {
			response.getWriter().print(Validate.result(TransactionDict.WEBSITE_NOT_EXIST, TransactionDict.MESSAGES.get(TransactionDict.WEBSITE_NOT_EXIST)));
			return;
		}

		// 交易存在和状态
		try {
			paramMap = Collections.synchronizedMap(new HashMap<String, Object>());
			paramMap.put("txnNo", StringUtil.split(website.getWebNo()));
			paramMap.put("txnOrder", request.getParameter("order"));
			paramMap.put("txnSite", website.getWebAddress ( ));
			transaction = transactionService.single(paramMap);
		} catch (Exception e) {
			response.getWriter().print(Validate.result(TransactionDict.TRANSACTION_FETCH_EXCEPTION, TransactionDict.MESSAGES.get(TransactionDict.TRANSACTION_FETCH_EXCEPTION)));
			return;
		}

		if (transaction == null) {
			response.getWriter().print(Validate.result(TransactionDict.TRANSACTION_NOT_EXIST, TransactionDict.MESSAGES.get(TransactionDict.TRANSACTION_NOT_EXIST)));
			return;
		}

		if (transaction.getTxnState().equals("0")) {
			jsonResult.put("version", GlobalDict.VERSION);
			jsonResult.put("no", subject.getSubNo());
			jsonResult.put("transaction", transaction.getTxnNo());
			jsonResult.put("order", transaction.getTxnOrder());
			jsonResult.put("cur", transaction.getTxnCur());
			jsonResult.put("loc", NumberUtil.transfer(transaction.getTxnLoc()));
			jsonResult.put("rate", NumberUtil.transfer(transaction.getTxnRate(), 4));
			jsonResult.put("amount", NumberUtil.transfer(transaction.getTxnAmount()));
			jsonResult.put("code", TransactionDict.TRANSACTION_FAILURE);
			jsonResult.put("message", TransactionDict.MESSAGES.get(TransactionDict.TRANSACTION_FAILURE));
			jsonResult.put("signature", DigestUtil.sha256(GlobalDict.VERSION+subject.getSubNo() + transaction.getTxnOrder() + NumberUtil.transfer(transaction.getTxnAmount ( )) +jsonResult.getString ( "code" )+ subject.getSubKey()));
			response.getWriter().print(jsonResult.toString());
			return;
		}

		
		jsonResult.put("version", GlobalDict.VERSION);
		jsonResult.put("no", subject.getSubNo());
		jsonResult.put("transaction", transaction.getTxnNo());
		jsonResult.put("order", transaction.getTxnOrder());
		jsonResult.put("cur", transaction.getTxnCur());
		jsonResult.put("loc", NumberUtil.transfer(transaction.getTxnLoc()));
		jsonResult.put("rate", NumberUtil.transfer(transaction.getTxnRate(), 4));
		jsonResult.put("amount", NumberUtil.transfer(transaction.getTxnAmount()));
		jsonResult.put("code", TransactionDict.TRANSACTION_SUCCESS);
		jsonResult.put("message", TransactionDict.MESSAGES.get(TransactionDict.TRANSACTION_SUCCESS));
		jsonResult.put("signature", DigestUtil.sha256(GlobalDict.VERSION+subject.getSubNo() + transaction.getTxnOrder() + NumberUtil.transfer(transaction.getTxnAmount ( )) +jsonResult.getString ( "code" )+ subject.getSubKey()));
		
		response.getWriter().print(jsonResult.toString());
		return;

	}

}
